import { updateFileTreeToDB } from "@/apis/admin/File";
import { restService } from "@/apis/rest";
import { getFileTree } from "@/apis/web/File";
import { useLocalStorage } from "@/hooks/useLocalStorage";
import { RootState } from "@/store";
import { setState } from "@/utils/core";
import { formatDateTime } from "@/utils/dayjs";
import dayjs from "dayjs";
import { ElAlert, ElMessage, ElMessageBox } from "element-plus";
import { Module } from "vuex";
import { IFileManagementActions, IFileManagementGetter, IFileManagementMutations, IFileManagementState } from "./types";

const state: IFileManagementState = {
    files: [],
    fileCount: 0,
    fileListPageAndSize: {
        page: 1,
        size: 10
    },
    dialogVisible: false,
    prefixPath: '',
    fileForm: {
        name: '',
        path: '',
        type: '',
        createdAt: '',
        updatedAt: '',
    },
    fileFromOpts: {
        type: [],
        path: [],
    },
    fileFolder: [
        // { label: "ID", prop: "_id", width: "100" },
        { label: "文件名", prop: "name", width: "100" },
        { label: "文件路径", prop: "path", width: "100" },
        { label: "文件类型", prop: "type", width: "100" },
        { label: "创建时间", prop: "createdAt", width: "100" },
        { label: "更新时间", prop: "updatedAt", width: "100" }
    ],
    fileFormComponent: {
        formStatus: "上传",
        formPlaceholder: {
            name: "请输入文件名",
            path: "请输入文件路径",
            type: "请输入文件类型",
            createdAt: "请选择创建时间",
            updatedAt: "请选择更新时间"
        },
        formControl: {
            submit: { value: '提交', type: 'primary' },
            reset: { value: '重置', type: 'default' }
        }
    },
    fileFormRules: {
        name: [{ required: true, message: "请输入文件名", trigger: "blur" }],
        path: [{ required: true, message: "请输入文件路径", trigger: "blur" }],
        type: [{ required: true, message: "请选择文件类型", trigger: "blur" }],
        createdAt: [{ message: "请选择创建时间", trigger: "blur", default: new Date() }],
        updatedAt: [{ message: "请选择更新时间", trigger: "blur", default: new Date() }]
    },
}

const actions: IFileManagementActions = {
    submitForm({ state, commit }) {
        commit('_submitForm')
        commit('_resetForm')
    },
    deleteFile({ commit }, row) {
        ElMessageBox.confirm(`此操作将永久删除文件${row.name}, 是否继续?`, '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
        }).then(() => {
            commit('_deleteFile', row._id)
        }).catch(() => {
            ElMessage({
                type: 'info',
                message: '已取消删除'
            });
        });
    }
}

const mutations: IFileManagementMutations = {
    _setState: (state, { path, value }) => {
        setState(state, path, value);
    },
    _resetForm: (state) => {
        Object.keys(state.fileForm).forEach((key) => state.fileForm[key] = '')
        state.fileFormComponent.formStatus = '添加'
    },
    _deleteFile: async (state, id) => {
        const res = await restService('file', { _id: id }).del()
        if (res && !res.message) {
            state.files = state.files.filter((item: any) => item._id !== id)
            ElMessage({
                type: 'success',
                message: '删除成功!'
            });
        }
    },
    _submitForm: async (state) => {
        const newFile = { ...state.fileForm }
        newFile.newSize && delete newFile.newSize
        newFile.uploadName && delete newFile.uploadName
        newFile.cameraName && delete newFile.cameraName
        newFile.shortPath && delete newFile.shortPath
        newFile.createdAt = dayjs(newFile.createdAt).toISOString();
        newFile.updatedAt = dayjs(newFile.updatedAt).toISOString();
        newFile.path = `${state.prefixPath}hVideo/${newFile.path.join('/')}`
        const res = await restService('file', newFile).update();
        if (res && !res.message) {
            console.log(res)
            state.files = state.files.map((item: any) => {
                if (item._id === res._id) {
                    res.createdAt = formatDateTime(res.createdAt)
                    res.updatedAt = formatDateTime(res.updatedAt)
                    res.uploader && (res.uploadName = res.uploader.username)
                    if (res.extname === 'mp4') {
                        res.size ? (res.newSize = (res.size / 1024 / 1024).toFixed(2) + 'MB') : (res.newSize = '0')
                    } else {
                        res.size ? (res.newSize = (res.size / 1024).toFixed(2) + 'KB') : (item.newSize = '0')
                    }
                    return res
                }
                return item
            })
        }
    },
    async _getFileList(state, payload) {
        const res = await restService('file').getList()
        if (res && !res.message) {
            state.files = res.map((item: any) => {
                item.createdAt = formatDateTime(item.createdAt)
                item.updatedAt = formatDateTime(item.updatedAt)
                item.uploader && (item.uploadName = item.uploader.username)
                if (item.extname === 'mp4') {
                    item.size ? (item.newSize = (item.size / 1024 / 1024).toFixed(2) + 'MB') : (item.newSize = '0')
                } else {
                    item.size ? (item.newSize = (item.size / 1024).toFixed(2) + 'KB') : (item.newSize = '0')
                }
                if (state.fileFromOpts.type.every((type: any) => type.value !== item.type)) {
                    state.fileFromOpts.type.push({
                        value: item.type,
                        label: item.type
                    })
                }
                return item
            })
        }
    },
    _getAndUpdateFileList: async (state, pageAndSize = {}) => {
        const { setLocalStorage } = useLocalStorage()
        pageAndSize['page'] = pageAndSize['page'] || state.fileListPageAndSize.page;
        pageAndSize['pageSize'] = pageAndSize['pageSize'] || state.fileListPageAndSize.size;
        const res = (await restService("file", pageAndSize).getList()) as any
        if (res && !res.message) {
            state.prefixPath = res[0].path.split('hVideo')[0]
            state.files = res.map((item) => {
                item.createdAt = formatDateTime(item.createdAt.toString());
                item.updatedAt = formatDateTime(item.updatedAt.toString());
                item.name && (item.name = item.name.split('.')[0])
                item.uploader && (item.uploadName = item.uploader.username)
                item.camera && (item.cameraName = item.camera.name)
                if (item.path) {
                    const parts = item.path.split('/')
                    parts.pop();
                    if (!parts.length) {
                        item.shortPath = '/'
                    } else {
                        const index = parts.indexOf('hVideo');
                        if (index >= 0 && index < parts.length - 1) {
                            item.shortPath = parts.slice(index + 1).join('/')
                        } else {
                            item.shortPath = '/'
                        }
                    }
                }
                if (item.extname === 'mp4') {
                    item.size ? (item.newSize = (item.size / 1024 / 1024).toFixed(2) + 'MB') : (item.newSize = '0')
                } else {
                    item.size ? (item.newSize = (item.size / 1024).toFixed(2) + 'KB') : (item.newSize = '0')
                }
                return item
            })

            state.files = [...res]
        }
    },
    _getFileCount: async (state) => {
        const res = await restService("file").getCount()
        if (res && !res.message) {
            state.fileCount = res.result
        }
    },
    async _updateFileTreeToDB(state, payload) {
        const res = await updateFileTreeToDB()
        console.log(res);
    },
    async _getFileTreeAndSetPathOpts(state, payload) {
        const res = await getFileTree() as any
        if (res && !res.message) {
            state.fileFromOpts.path = convertToTreeStructure(res)
        }
        function convertToTreeStructure(data) {
            function processChildren(children) {
                if (!children || children.length === 0) {
                    return [];
                }

                return children
                    .filter(child => child.type === 'directory')
                    .map(child => ({
                        value: child.name,
                        label: child.name,
                        children: processChildren(child.children),
                    }));
            }

            return processChildren(data.children);
        }
    }
}
const getters: IFileManagementGetter = {
    getFileList(state) {
        return state.files
    },
    getFileCount(state) {
        return state.fileCount
    },
    getSize(state) {
        return state.fileListPageAndSize.size
    },
    getPage(state) {
        return state.fileListPageAndSize.page
    }
}

export const fileManagement: Module<IFileManagementState, RootState> = {
    namespaced: true,
    state,
    actions,
    mutations,
    getters,
}
